package main

import (
	"bytes"
	"crypto/sha256"
	"math/big"
)

// ProofOfWork 挖矿模块
// ProofOfWork 工作量证明机制
type ProofOfWork struct {
	block *Block
	target *big.Int
}
//CreatePOW 创建ProofOfWork
func CreatePOW(block *Block) *ProofOfWork{
	pow := ProofOfWork{
		block: block,
	}
	target :=  "0000100000000000000000000000000000000000000000000000000000000000"
	bigNum := big.Int{}
	//res是指针类型的
	res, _ := bigNum.SetString(target, 16)
	pow.target = res
    return &pow
}
//Run 返回一个Hash值和随机数
func (pow *ProofOfWork) Run()([]byte, uint64){
	tmpBigInt := &big.Int{}
	//与给定的目标哈希值进行比较,小于则挖矿成功
	var nonce uint64 = 0
	var hash [32]byte
	for{
		block := pow.block
		tem := [][]byte{
			Uint64ConvertByte(block.Version),
			block.PreBlockHash,
			block.MerkelRoot,
			Uint64ConvertByte(block.TimeStamp),
			Uint64ConvertByte(block.Difficulty),
			Uint64ConvertByte(nonce),
			block.Data,
		}
		// blockInfo 拼装好的数据
		blockInfo := bytes.Join(tem, []byte(""))
		hash = sha256.Sum256(blockInfo)
		tmpBigInt.SetBytes(hash[:])
		res := tmpBigInt.Cmp(pow.target)
		if res == -1{
			break
		}
		nonce ++
	}
   return hash[:],nonce
}